<template>
    <section class="person_form">
        <div class="team_container">
            <div class="team_info">
                <n-upload accept="image/*" color="#8590a6" :custom-request="customRequestTeam1" list-type="image-card"
                    :max="1" @before-upload="beforeAvatarUpload" :default-file-list="team1FileList">
                    {{ $t('text.team1logo') }}
                </n-upload>
                <n-input v-model:value="team1.teamName" type="text" placeholder="Team One's Name" />
            </div>
            <n-input-group>
                <img src="../../assets/images/survivor.png" class="aside_image" />
                <n-input v-model:value="team1.survivor1.name" :disabled="team1.survivor1.take" type="text"
                    placeholder="Suvivor1" />
                <n-button :type="!team1.survivor1.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team1', 'survivor1', 'survivor')">{{ team1.survivor1.take ?
                        $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/survivor.png" class="aside_image" />
                <n-input v-model:value="team1.survivor2.name" :disabled="team1.survivor2.take" type="text"
                    placeholder="Suvivor2" />
                <n-button :type="!team1.survivor2.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team1', 'survivor2', 'survivor')">{{ team1.survivor2.take ?
                        $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/survivor.png" class="aside_image" />
                <n-input v-model:value="team1.survivor3.name" :disabled="team1.survivor3.take" type="text"
                    placeholder="Suvivor3" />
                <n-button :type="!team1.survivor3.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team1', 'survivor3', 'survivor')">{{ team1.survivor3.take ?
                        $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/survivor.png" class="aside_image" />
                <n-input v-model:value="team1.survivor4.name" :disabled="team1.survivor4.take" type="text"
                    placeholder="Suvivor4" />
                <n-button :type="!team1.survivor4.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team1', 'survivor4', 'survivor')">{{ team1.survivor4.take ?
                        $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/survivor.png" class="aside_image" />
                <n-input v-model:value="team1.survivor5.name" :disabled="team1.survivor5.take" type="text"
                    placeholder="Suvivor5" />
                <n-button :type="!team1.survivor5.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team1', 'survivor5', 'survivor')">{{ team1.survivor5.take ?
                        $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/survivor.png" class="aside_image" />
                <n-input v-model:value="team1.survivor6.name" :disabled="team1.survivor6.take" type="text"
                    placeholder="Suvivor6" />
                <n-button :type="!team1.survivor6.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team1', 'survivor6', 'survivor')">{{ team1.survivor6.take ?
                        $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/hunter.png" class="aside_image" />
                <n-input v-model:value="team1.hunter1.name" :disabled="team1.hunter1.take" type="text"
                    placeholder="Hunter1" />
                <n-button :type="!team1.hunter1.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team1', 'hunter1', 'hunter')">{{ team1.hunter1.take ? $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/hunter.png" class="aside_image" />
                <n-input v-model:value="team1.hunter2.name" :disabled="team1.hunter2.take" type="text"
                    placeholder="Hunter2" />
                <n-button :type="!team1.hunter2.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team1', 'hunter2', 'hunter')">{{ team1.hunter2.take ? $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/hunter.png" class="aside_image" />
                <n-input v-model:value="team1.hunter3.name" :disabled="team1.hunter3.take" type="text"
                    placeholder="Hunter3" />
                <n-button :type="!team1.hunter3.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team1', 'hunter3', 'hunter')">{{ team1.hunter3.take ? $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
        </div>
        <div class="team_container">
            <div class="team_info">
                <n-upload accept="image/*" color="#8590a6" :custom-request="customRequestTeam2" list-type="image-card"
                    :max="1" @before-upload="beforeAvatarUpload" :default-file-list="team2FileList">
                    {{ $t('text.team2logo') }}
                </n-upload>
                <n-input v-model:value="team2.teamName" type="text" placeholder="Team Two's Name" />
            </div>
            <n-input-group>
                <img src="../../assets/images/survivor.png" class="aside_image" />
                <n-input v-model:value="team2.survivor1.name" :disabled="team2.survivor1.take" type="text"
                    placeholder="Suvivor1" />
                <n-button :type="!team2.survivor1.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team2', 'survivor1', 'survivor')">{{ team2.survivor1.take ?
                        $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/survivor.png" class="aside_image" />
                <n-input v-model:value="team2.survivor2.name" :disabled="team2.survivor2.take" type="text"
                    placeholder="Suvivor2" />
                <n-button :type="!team2.survivor2.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team2', 'survivor2', 'survivor')">{{ team2.survivor2.take ?
                        $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/survivor.png" class="aside_image" />
                <n-input v-model:value="team2.survivor3.name" :disabled="team2.survivor3.take" type="text"
                    placeholder="Suvivor3" />
                <n-button :type="!team2.survivor3.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team2', 'survivor3', 'survivor')">{{ team2.survivor3.take ?
                        $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/survivor.png" class="aside_image" />
                <n-input v-model:value="team2.survivor4.name" :disabled="team2.survivor4.take" type="text"
                    placeholder="Suvivor4" />
                <n-button :type="!team2.survivor4.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team2', 'survivor4', 'survivor')">{{ team2.survivor4.take ?
                        $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/survivor.png" class="aside_image" />
                <n-input v-model:value="team2.survivor5.name" :disabled="team2.survivor5.take" type="text"
                    placeholder="Suvivor5" />
                <n-button :type="!team2.survivor5.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team2', 'survivor5', 'survivor')">{{ team2.survivor5.take ?
                        $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/survivor.png" class="aside_image" />
                <n-input v-model:value="team2.survivor6.name" :disabled="team2.survivor6.take" type="text"
                    placeholder="Suvivor6" />
                <n-button :type="!team2.survivor6.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team2', 'survivor6', 'survivor')">{{ team2.survivor6.take ?
                        $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/hunter.png" class="aside_image" />
                <n-input v-model:value="team2.hunter1.name" :disabled="team2.hunter1.take" type="text"
                    placeholder="Hunter1" />
                <n-button :type="!team2.hunter1.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team2', 'hunter1', 'hunter')">{{ team2.hunter1.take ? $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/hunter.png" class="aside_image" />
                <n-input v-model:value="team2.hunter2.name" :disabled="team2.hunter2.take" type="text"
                    placeholder="Hunter2" />
                <n-button :type="!team2.hunter2.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team2', 'hunter2', 'hunter')">{{ team2.hunter2.take ? $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
            <n-input-group>
                <img src="../../assets/images/hunter.png" class="aside_image" />
                <n-input v-model:value="team2.hunter3.name" :disabled="team2.hunter3.take" type="text"
                    placeholder="Hunter3" />
                <n-button :type="!team2.hunter3.take ? 'primary' : 'error'"
                    @click="checkPersonTake('team2', 'hunter3', 'hunter')">{{ team2.hunter3.take ? $t('text.off') :
                        $t('text.on') }}</n-button>
            </n-input-group>
        </div>
    </section>
    <AsgTeamSelect @emitMemeber="handleTeamFill" />
    <section class="operation_button">
        <n-button-group>
            <n-button size="small" strong secondary type="error" @click="handleExportTeamFile('team1')">
                <template #icon>
                    <ArrowUpCircleSharp />
                </template>
                导入战队文件到左侧信息
            </n-button>
            <n-button size="small" strong secondary type="info" @click="handleExportTeamFile('team2')">
                <template #icon>
                    <ArrowUpCircleSharp />
                </template>
                导入战队文件到右侧信息
            </n-button>
            <n-button size="small" :loading="updateLoading" type="info" @click="handleValidateForm">
                <template #icon>
                    <Eye />
                </template>
                {{ $t('button.updatePerson') }}
            </n-button>
        </n-button-group>
    </section>
</template>

<script setup lang='ts' name="TeamInfo">
import BoardChannel from '@/utils/boardChannel';
import { Eye, ArrowUpCircleSharp } from '@vicons/ionicons5';
import { UploadCustomRequestOptions, UploadFileInfo, useMessage } from 'naive-ui';
import { reactive } from 'vue';
import storeHelper from '@/utils/TauriStore';
import AsgTeamSelect from './AsgTeamSelect.vue';
import { ask, open } from '@tauri-apps/plugin-dialog';
import { readTextFile } from '@tauri-apps/plugin-fs';

const channel = new BoardChannel('bp-system');
const message = useMessage();

type TeamKey = 'team1' | 'team2';
type PersonType = 'survivor' | 'hunter';

interface Person {
    name: string;
    take: boolean;
}

interface Team {
    teamName: string;
    logo: string;
    survivor1: Person;
    survivor2: Person;
    survivor3: Person;
    survivor4: Person;
    survivor5: Person;
    survivor6: Person;
    hunter1: Person;
    hunter2: Person;
    hunter3: Person;
}

interface StoreTeam {
    team1: {
        hunter: string
        logo: string
        survivor: string[]
        teamName: string
    },
    team2: {
        hunter: string
        logo: string
        survivor: string[]
        teamName: string
    }
}
//API
interface ApiTeam {
    team1: {
        hunter: string[]
        survivor: string[]
        teamName: string
    },
    team2: {
        hunter: string[]
        survivor: string[]
        teamName: string
    }
}

// loading
const updateLoading = ref(false);
const handleTeamFill = (teamMember: ApiTeam) => {
    team1.teamName = teamMember.team1.teamName;
    teamMember.team1.survivor.forEach((sur: string, index: number) => {
        team1[`survivor${index + 1}` as Exclude<keyof Team, 'teamName' | 'logo'>].name = sur;
    });
    teamMember.team1.hunter.forEach((hun: string, index: number) => {
        team1[`hunter${index + 1}` as Exclude<keyof Team, 'teamName' | 'logo'>].name = hun;
    });
    team2.teamName = teamMember.team2.teamName;
    teamMember.team2.survivor.forEach((sur: string, index: number) => {
        team2[`survivor${index + 1}` as Exclude<keyof Team, 'teamName' | 'logo'>].name = sur;
    });
    teamMember.team2.hunter.forEach((hun: string, index: number) => {
        team2[`hunter${index + 1}` as Exclude<keyof Team, 'teamName' | 'logo'>].name = hun;
    });
}
const team1FileList = reactive<UploadFileInfo[]>([]);
const team2FileList = reactive<UploadFileInfo[]>([]);
// 检测四个求生
function survivorFull(teamKey: TeamKey): boolean {
    const team = teamKey === 'team1' ? team1 : team2;
    const survivorKeys = ['survivor1', 'survivor2', 'survivor3', 'survivor4', 'survivor5', 'survivor6'] as const;

    let surCount = 0;

    for (const key of survivorKeys) {
        if (team[key].take) {
            surCount++;
            if (surCount > 4) {
                return false;
            }
        }
    }

    return surCount >= 4;
}

function hunterFull(teamKey: TeamKey): boolean {
    const team = teamKey === 'team1' ? team1 : team2;
    const hunterKeys = ['hunter1', 'hunter2', 'hunter3'] as const;
    let hunCount = 0;

    for (const key of hunterKeys) {
        if (team[key].take) {
            hunCount++;
            if (hunCount > 1) {
                return false;
            }
        }
    }
    return hunCount >= 1;
}

const checkPersonTake = (teamKey: TeamKey, prop: keyof Omit<Team, "logo" | "teamName">, type: PersonType) => {
    const team = teamKey === 'team1' ? team1 : team2;
    const nowName = team[prop].name; //名称
    if (!nowName) return message.error('请填写选手名称！');
    const nowState = team[prop].take; // true为上场
    if (survivorFull(teamKey) && type === 'survivor' && !nowState) {
        return message.error('已有四位求生上场，请检查！');
    }
    if (hunterFull(teamKey) && type === 'hunter' && !nowState) {
        return message.error('已有一位监管上场，请检查！');
    }
    team[prop].take = !nowState;
}

const team1 = reactive<Team>({
    logo: '',
    teamName: '',
    survivor1: {
        name: '',
        take: false
    },
    survivor2: {
        name: '',
        take: false
    },
    survivor3: {
        name: '',
        take: false
    },
    survivor4: {
        name: '',
        take: false
    },
    survivor5: {
        name: '',
        take: false
    },
    survivor6: {
        name: '',
        take: false
    },
    hunter1: {
        name: '',
        take: false
    },
    hunter2: {
        name: '',
        take: false
    },
    hunter3: {
        name: '',
        take: false
    }
});

const team2 = reactive<Team>({
    logo: '',
    teamName: '',
    survivor1: {
        name: '',
        take: false
    },
    survivor2: {
        name: '',
        take: false
    },
    survivor3: {
        name: '',
        take: false
    },
    survivor4: {
        name: '',
        take: false
    },
    survivor5: {
        name: '',
        take: false
    },
    survivor6: {
        name: '',
        take: false
    },
    hunter1: {
        name: '',
        take: false
    },
    hunter2: {
        name: '',
        take: false
    },
    hunter3: {
        name: '',
        take: false
    }
});

// 头像上传
const beforeAvatarUpload = (options: {
    'file': UploadFileInfo
}) => {
    const { file } = options.file;
    if (!file) {
        return false;
    }
    if (file.size > 10 ** 6) {
        message.error('图片文件大小不能大于1MB');
        return false;
    }
    return true;
};

const customRequestTeam1 = ({ file }: UploadCustomRequestOptions) => {
    if (!file.file) {
        return;
    }
    const reader = new FileReader();
    reader.readAsDataURL(file.file);
    reader.addEventListener(
        'load',
        async (event) => {
            const result = event.target?.result;
            if (typeof result !== 'string') {
                return;
            }
            team1.logo = result;
        }
    );
};
const customRequestTeam2 = ({ file }: UploadCustomRequestOptions) => {
    if (!file.file) {
        return;
    }
    const reader = new FileReader();
    reader.readAsDataURL(file.file);
    reader.addEventListener(
        'load',
        async (event) => {
            const result = event.target?.result;
            if (typeof result !== 'string') {
                return;
            }
            team2.logo = result;
        }
    );
};
// 校验是否都上场
const handleValidateForm = () => {
    if (!survivorFull('team1')) return message.error('战队1求生上场数量少于4，请检查！');
    if (!hunterFull('team1')) return message.error('战队1监管上场数量少于1，请检查！');
    if (!survivorFull('team2')) return message.error('战队2求生上场数量少于4，请检查！');
    if (!hunterFull('team2')) return message.error('战队2监管上场数量少于1，请检查！');
    if (!team1.logo || !team1.teamName) return message.error('战队1缺乏战队LOGO和战队名称');
    if (!team2.logo || !team2.teamName) return message.error('战队2缺乏战队LOGO和战队名称');
    createGame();
}
const createGame = async () => {
    try {
        updateLoading.value = true;
        const teamInfo: TeamInfo = {
            team1: {
                logo: '',
                teamName: '',
                survivor: [],
                hunter: ''
            },
            team2: {
                logo: '',
                teamName: '',
                survivor: [],
                hunter: ''
            }
        }
        for (const key in team1) {
            const data = team1[key as keyof Team];
            if (key.startsWith('survivor')) {
                if (typeof data === 'object' && 'take' in data && data.take) {
                    teamInfo.team1.survivor.push(data.name)
                }
            } else if (key === 'logo' && typeof data === 'string') {
                teamInfo.team1.logo = data;
            } else if (key === 'teamName' && typeof data === 'string') {
                teamInfo.team1.teamName = data;
            } else if (key.startsWith('hunter') && typeof data === 'object' && 'take' in data && data.take) {
                teamInfo.team1.hunter = data.name;
            }
        }
        for (const key in team2) {
            const data = team2[key as keyof Team];
            if (key.startsWith('survivor')) {
                if (typeof data === 'object' && 'take' in data && data.take) {
                    teamInfo.team2.survivor.push(data.name)
                }
            } else if (key === 'logo' && typeof data === 'string') {
                teamInfo.team2.logo = data;
            } else if (key === 'teamName' && typeof data === 'string') {
                teamInfo.team2.teamName = data;
            } else if (key.startsWith('hunter') && typeof data === 'object' && 'take' in data && data.take) {
                teamInfo.team2.hunter = data.name;
            }
        }
        await storeHelper.set('hasGame', true);
        await storeHelper.set('teamInfo', teamInfo);
        // 派发更新
        channel.send('teamInfoChange', true);
        message.success('Update Successfully!');
    } finally {
        updateLoading.value = false;
    }
}
const _init = async () => {
    try {
        const teamInformation = await storeHelper.get('teamInfo') as StoreTeam;
        if (teamInformation && typeof teamInformation === 'object') {
            team1.logo = teamInformation.team1.logo;
            if (team1.logo) {
                team1FileList.splice(0);
                team1FileList.push({
                    'id': 'team1',
                    'name': 'LOGO',
                    'status': 'finished',
                    'url': team1.logo,
                });
            }
            team1.teamName = teamInformation.team1.teamName;
            teamInformation.team1.survivor.forEach((sur: string, index: number) => {
                team1[`survivor${index + 1}` as Exclude<keyof Team, 'teamName' | 'logo'>].name = sur;
            });
            team1.hunter1.name = teamInformation.team1.hunter;
            team2.logo = teamInformation.team2.logo;
            if (team2.logo) {
                team2FileList.splice(0);
                team2FileList.push({
                    'id': 'team2',
                    'name': 'LOGO',
                    'status': 'finished',
                    'url': team1.logo,
                });
            }
            team2.teamName = teamInformation.team2.teamName;
            teamInformation.team2.survivor.forEach((sur: string, index: number) => {
                team2[`survivor${index + 1}` as Exclude<keyof Team, 'teamName' | 'logo'>].name = sur;
            });
            team2.hunter1.name = teamInformation.team2.hunter;
        }
    } catch (error) {
        console.log(error);
    }
}

function isObjectAndExists(value: unknown): boolean {
    return value !== null && value !== undefined && typeof value === 'object' && !Array.isArray(value);
}
// 导入战队
const handleExportTeamFile = async (type: 'team1' | 'team2') => {
    try {
        const answer = await ask('导入JSON战队信息将覆盖现填写的战队信息，请问是否继续?', {
            title: '警告',
            kind: 'warning',
        });
        if (!answer) throw new Error('取消');
        const file = await open({
            multiple: false,
            directory: false,
            filters: [{ name: 'JSON', extensions: ['json'] }]
        });
        if (!file) throw new Error('文件不存在！');
        const content = await readTextFile(file);
        const jsonData = JSON.parse(content);
        if (!isObjectAndExists(jsonData)) throw new Error('JSON数据不符合格式要求！');
        if (type === 'team1') {
            Object.assign(team1, jsonData);
            if (team1.logo) {
                team1FileList.splice(0);
                team1FileList.push({
                    'id': 'team1',
                    'name': 'LOGO',
                    'status': 'finished',
                    'url': team1.logo,
                });
            }
        } else {
            Object.assign(team2, jsonData);
            if (team2.logo) {
                team2FileList.splice(0);
                team2FileList.push({
                    'id': 'team1',
                    'name': 'LOGO',
                    'status': 'finished',
                    'url': team2.logo,
                });
            }
        }
        message.success('导入战队信息成功!');
    } catch (error) {
        message.error(error instanceof Error ? error.message : '未知错误！');
    }
}
// 挂在
onMounted(() => {
    _init();
})
</script>

<style scoped lang='scss'>
// 组织
.person_form {

    display: grid;
    grid-template-columns: repeat(2, 1fr);

    .team_container {
        padding: 1em;
        display: flex;
        flex-direction: column;
        gap: 1em;

        .team_info {
            display: flex;
            align-items: flex-end;
            justify-content: space-between;
            gap: 1em;
        }
    }
}

//操作按钮
.operation_button {
    padding: 1em;
    display: flex;
    justify-content: flex-end;
}

.aside_image {
    width: 34px;
    height: 34px;
    border: 1px solid rgb(224, 224, 230);
    background: #E7E7E7;
}
</style>